<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Jboot | 开始使用Jboot</title>
    <meta name="description" content="一个开源的分布式、商业级微服务框架">
    
    
    <link rel="preload" href="/assets/css/5.styles.1d6de0dd.css" as="style"><link rel="preload" href="/assets/js/app.7f52c12a.js" as="script"><link rel="preload" href="/assets/js/0.06af09ca.js" as="script"><link rel="prefetch" href="/assets/js/1.f8730824.js"><link rel="prefetch" href="/assets/js/2.676f353b.js"><link rel="prefetch" href="/assets/js/3.aba6aeba.js"><link rel="prefetch" href="/assets/js/4.f18705ea.js">
    <link rel="stylesheet" href="/assets/css/5.styles.1d6de0dd.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/" class="home-link router-link-active"><!----><span class="site-name">
      Jboot
    </span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/started/" class="nav-link router-link-exact-active router-link-active">开始</a></div><div class="nav-item"><a href="/docs/" class="nav-link">文档</a></div><div class="nav-item"><a href="/benchmark/" class="nav-link">性能</a></div><div class="nav-item"><a href="https://www.oschina.net/question/tag/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">提问</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">源码下载</span><span class="arrow right"></span></a><ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----><a href="https://gitee.com/fuhai/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">Gitee</a></li><li class="dropdown-item"><!----><a href="https://github.com/yangfuhai/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">Github</a></li></ul></div></div><!----></nav></div></header><div class="sidebar-mask"></div><div class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">首页</a></div><div class="nav-item"><a href="/started/" class="nav-link router-link-exact-active router-link-active">开始</a></div><div class="nav-item"><a href="/docs/" class="nav-link">文档</a></div><div class="nav-item"><a href="/benchmark/" class="nav-link">性能</a></div><div class="nav-item"><a href="https://www.oschina.net/question/tag/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">提问</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">源码下载</span><span class="arrow right"></span></a><ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----><a href="https://gitee.com/fuhai/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">Gitee</a></li><li class="dropdown-item"><!----><a href="https://github.com/yangfuhai/jboot" target="_blank" rel="noopener noreferrer" class="nav-link">Github</a></li></ul></div></div><!----></nav><ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>开始使用Jboot</span><!----></p><ul class="sidebar-group-items"><li><a href="/started/#创建项目" class="sidebar-link">创建项目</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/started/#通过-intellij-idea-创建项目" class="sidebar-link">通过 IntelliJ IDEA  创建项目</a></li><li class="sidebar-sub-header"><a href="/started/#通过-eclipse-创建项目" class="sidebar-link">通过 Eclipse 创建项目</a></li></ul></li><li><a href="/started/#maven-依赖" class="sidebar-link">Maven 依赖</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#hello-world" class="sidebar-link">Hello World</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#链接数据库" class="sidebar-link">链接数据库</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#使用代码生成器" class="sidebar-link">使用代码生成器</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#自动注入" class="sidebar-link">自动注入</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#数据库的增删改查" class="sidebar-link">数据库的增删改查</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/started/#分页查询" class="sidebar-link">分页查询</a></li><li class="sidebar-sub-header"><a href="/started/#新增功能" class="sidebar-link">新增功能</a></li><li class="sidebar-sub-header"><a href="/started/#修改功能" class="sidebar-link">修改功能</a></li><li class="sidebar-sub-header"><a href="/started/#删除功能" class="sidebar-link">删除功能</a></li></ul></li><li><a href="/started/#使用缓存提高性能" class="sidebar-link">使用缓存提高性能</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/started/#探索jboot的更多功能" class="sidebar-link">探索Jboot的更多功能...</a><ul class="sidebar-sub-headers"></ul></li></ul></div></li></ul></div><div class="page"><div class="content"><h1 id="开始使用jboot"><a href="#开始使用jboot" aria-hidden="true" class="header-anchor">#</a> 开始使用Jboot</h1><p>Jboot 使用到了如下的技术，了解 Jboot 之前，请先保证您已经了掌握如下技术：</p><ul><li>熟悉 Java 编程语言</li><li>熟悉 maven 的基本原理</li><li>熟悉 IntelliJ IDEA 或者 Eclipse 等编辑器的使用</li></ul><p>交流 QQ 群:</p><ul><li>群1：601440615 （已满）</li><li>群2：719614554 （开放中）</li></ul><h2 id="创建项目"><a href="#创建项目" aria-hidden="true" class="header-anchor">#</a> 创建项目</h2><h3 id="通过-intellij-idea-创建项目"><a href="#通过-intellij-idea-创建项目" aria-hidden="true" class="header-anchor">#</a> 通过 IntelliJ IDEA  创建项目</h3><p>IntelliJ IDEA 下载地址：https://www.jetbrains.com/idea/ ，下载完成后完成后开始安装，安装过程略。</p><p>第一步：打开 IntelliJ IDEA 创建 maven 项目，如下图：
<img src="/assets/img/idea_001.7afd2f53.jpg" alt></p><p>第二步：填写 maven 项目的 GroupId、ArtifactId 和 Version</p><ul><li>GroupId 一般是包名，用来做项目的唯一标识</li><li>ArtifactId 一般是项目名</li><li>Version 是项目的版本
<img src="/assets/img/idea_002.76ecd666.png" alt></li></ul><p>第三步：填写 项目存储路径
<img src="/assets/img/idea_003.5d8e6245.png" alt></p><p>创建完毕后，我们会看到如下图所示，注意点击 Enable Auto-Import.
<img src="/assets/img/idea_004.8e38c226.png" alt></p><h3 id="通过-eclipse-创建项目"><a href="#通过-eclipse-创建项目" aria-hidden="true" class="header-anchor">#</a> 通过 Eclipse 创建项目</h3><p>略，和 通过 IntelliJ IDEA  创建项目 基本相同。</p><h2 id="maven-依赖"><a href="#maven-依赖" aria-hidden="true" class="header-anchor">#</a> Maven 依赖</h2><p>通过 以上步骤建立项目后，我们会在项目目录下找到 pom.xml 文件，这个文件是 maven 的核心文件，maven 是通过 pom.xml 对项目进行依赖配置和管理的。</p><p>我们需要在 pom.xml 里添加对 Jboot 的依赖配置，如下代码：</p><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>io.jboot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>jboot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>1.5.2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>如下图所示：
<img src="/assets/img/idea_005.3af1eb31.png" alt></p><h2 id="hello-world"><a href="#hello-world" aria-hidden="true" class="header-anchor">#</a> Hello World</h2><p>一般情况下，对一个新项目的了解是从 Hello World 开始的，因此，我们需要通过 Jboot 来写一个 Hello World 程序。</p><p>这个 Hello World 的需求是：</p><blockquote><p><strong>通过编写代码，我们在浏览器访问后输出 “Hello World Jboot” 的文字内容。</strong></p></blockquote><p>通过以上步骤，我们创建好了项目、添加好了 jboot 的maven依赖，接下来我们需要来创建一个叫 IndexController 的java文件，
<img src="/assets/img/idea_006.9206f5be.png" alt><img src="/assets/img/idea_007.57bbed25.png" alt></p><p>IndexController 的代码如下：</p><pre class="language-java"><code><span class="token keyword">import</span> io<span class="token punctuation">.</span>jboot<span class="token punctuation">.</span>Jboot<span class="token punctuation">;</span>
<span class="token keyword">import</span> io<span class="token punctuation">.</span>jboot<span class="token punctuation">.</span>web<span class="token punctuation">.</span>controller<span class="token punctuation">.</span>JbootController<span class="token punctuation">;</span>
<span class="token keyword">import</span> io<span class="token punctuation">.</span>jboot<span class="token punctuation">.</span>web<span class="token punctuation">.</span>controller<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>RequestMapping<span class="token punctuation">;</span>

<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IndexController</span> <span class="token keyword">extends</span> <span class="token class-name">JbootController</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">renderText</span><span class="token punctuation">(</span><span class="token string">&quot;Hello World Jboot&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>


    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        Jboot<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>以上代码需要注意以下几点：</p><ol><li>IndexController 需要继承 JbootController 或者 Controller</li><li>需要添加 @RequestMapping(&quot;/&quot;) 请求映射配置</li><li>通过编写 <code>index()</code> 方法来接收请求，并向浏览器输出 &quot;Hello World Jboot&quot; , 此处注意：必须叫 <code>index()</code>  不能修改名字，后续会讲到其原理。</li></ol><p>通过运行 IndexController 的 main() 方法，我们可以看到如下的日志输出：</p><pre class="language-text"><code>May 10, 2018 5:10:42 PM io.jboot.config.JbootConfigManager warn
警告: Could not find jboot.properties in your class path.
  ____  ____    ___    ___   ______ 
 |    ||    \  /   \  /   \ |      |
 |__  ||  o  )|     ||     ||      |
 __|  ||     ||  O  ||  O  ||_|  |_|
/  |  ||  O  ||     ||     |  |  |  
\  `  ||     ||     ||     |  |  |  
 \____||_____| \___/  \___/   |__|  
                                    
JbootConfig {version='1.5.2', mode='dev', bannerEnable=true, bannerFile='banner.txt', jfinalConfig='io.jboot.web.JbootAppConfig'}
JbootServerConfig {type='undertow', host='0.0.0.0', port=8080, contextPath='/'}
JbootWebConfig {actionCacheEnable=true, actionCacheKeyGeneratorType='default', websocketEnable=false, websocketBufferPoolSize=100, cookieEncryptKey='JBOOT_DEFAULT_ENCRYPT_KEY'}
server classPath : /Users/michael/work/git/jbootdemo/target/classes
server webRoot : /Users/michael/work/git/jbootdemo/target/classes
server started success , url : http://127.0.0.1:8080/
</code></pre><p>我们看到最后一行日志的内容是：</p><pre class="language-text"><code>server started success , url : http://127.0.0.1:8080/
</code></pre><p>此时我们通过浏览器访问：http://127.0.0.1:8080 , 就可以看到如下内容：
<img src="/assets/img/0008.e3d74faa.png" alt></p><h2 id="链接数据库"><a href="#链接数据库" aria-hidden="true" class="header-anchor">#</a> 链接数据库</h2><p>在 Java Web 开发中，几乎 99% 以上的项目都需要和数据库打交道，因此，了解 Jboot 如何连接数据成为了必须。</p><p>通过 Jboot 连接数据库只需要做两步：</p><ol><li>创建 jboot.properties 配置文件</li><li>在 jboot.properties 添加数据库连接信息</li></ol><p>第一步：在项目的resource目录下创建 jboot.properties 文件，此时，项目的目录结构应该如下：</p><pre class="language-text"><code>├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── IndexController.java
│   │   └── resources
│   │       └── jboot.properties #注意文件目录不要错了
│   └── test
│       └── java
</code></pre><p>第二步：在 jboot.properties 文件添加如下数据库信息：</p><pre class="language-text"><code>jboot.datasource.type = mysql
jboot.datasource.url = jdbc:mysql://127.0.0.1:3306/jbootdemo
jboot.datasource.user = root 
jboot.datasource.password =
</code></pre><ul><li>jboot.datasource.type：配置的是数据库的类型，目前 Jboot 支持的数据库类型有：Mysql 、Oracle 、SqlServer 、Postgresql 、Sqlite 和 其他标准的数据库。</li><li>jboot.datasource.url： 配置的是数据库的连接信息</li><li>jboot.datasource.user： 配置的是数据库的连接账号</li><li>jboot.datasource.password： 配置的是数据库的连接密码，没有密码可以留空</li></ul><p>通过配置完毕后，Jboot就已经有了访问数据库的能力，我们可以在 IndexController 写一个 <code>dbtest()</code> 方法，来测试下 Jboot 的数据库访问能力，代码如下：</p><pre class="language-text"><code>@RequestMapping(&quot;/&quot;)
public class IndexController extends JbootController {

    public void index() {
        renderText(&quot;Hello World Jboot&quot;);
    }

    public void dbtest(){
        List&lt;Record&gt; records = Db.find(&quot;select * from user&quot;);
        renderText(Arrays.toString(records.toArray()));
    }


    public static void main(String[] args) {
        Jboot.run(args);
    }
}
</code></pre><p>注意：以上代码能够正式运行的前提是：</p><ol><li>你本地安装好mysql数据库，并创建好库 <code>jbootdemo</code> ，因为数据库的连接url是：<code>jdbc:mysql://127.0.0.1:3306/jbootdemo</code></li><li>jbootdemo 下要有数据表 user，因为 sql 查询内容是：<code>select * from user</code></li></ol><p>例如：作者本地数据库的内容如下：
<img src="/assets/img/0010.8df8186d.png" alt></p><p>运行 IndexController 的 <code>main()</code> 方法，并访问 <code>http://127.0.0.1:8080/dbtest</code>，会看到如下内容所示：
<img src="/assets/img/0009.6e2b7902.png" alt></p><p>此时，证明 Jboot 已经能够准确访问数据库。</p><h2 id="使用代码生成器"><a href="#使用代码生成器" aria-hidden="true" class="header-anchor">#</a> 使用代码生成器</h2><p>Jboot 内置了一个简易的代码生成器，通过代码生成器运行，Jboot帮开发者生成每个数据库表对应 java 的 model 实体类，同时可以生成带有增、删、改、查基本数据库操作能力的 service 层代码。</p><p>在使用 Jboot 代码生成器之前，我们需要在 jboot.properties 配置好数据库的连接信息（以上内容已经提到）。并编写任意名字带有<code>main()</code>方法的执行类，例如我们叫 CodeGenerator， 代码如下：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CodeGenerator</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String args<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token comment">//依赖model的包名</span>
        String modelPackage <span class="token operator">=</span> <span class="token string">&quot;com.xxx.model&quot;</span><span class="token punctuation">;</span>
        <span class="token comment">//生成service 的包名</span>
        String basePackage <span class="token operator">=</span> <span class="token string">&quot;com.xxx.service&quot;</span><span class="token punctuation">;</span>

        JbootModelGenerator<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>modelPackage<span class="token punctuation">)</span><span class="token punctuation">;</span>
        JbootServiceGenerator<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>basePackage<span class="token punctuation">,</span> modelPackage<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>运行 CodeGenerator 的 <code>main()</code> 方法之后，我们能看到 Jboot 已经帮我们创建好对应的包名和类名，此时，项目的目录如下：</p><pre class="language-text"><code>├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── CodeGenerator.java
│   │   │   ├── IndexController.java
│   │   │   └── com
│   │   │       └── xxx
│   │   │           ├── model
│   │   │           │   ├── Article.java
│   │   │           │   ├── User.java
│   │   │           │   └── base
│   │   │           │       ├── BaseArticle.java
│   │   │           │       └── BaseUser.java
│   │   │           └── service
│   │   │               ├── ArticleService.java
│   │   │               ├── UserService.java
│   │   │               └── impl
│   │   │                   ├── ArticleServiceImpl.java
│   │   │                   └── UserServiceImpl.java
│   │   └── resources
│   │       └── jboot.properties
│   └── test
│       └── java
</code></pre><p>通过 Jboot 代码生成器的运行，项目对应的 model 类和 service 会自动生成，同时 Service 层的代码以及带有了对数据库增、删、改、查的基本能力.</p><p>需要注意的是：
<strong>再次运行该代码生成器的时候，BaseUser、BaseArticle会被重新覆盖，其他代码不会被覆盖。</strong> 若需要重新生成 service 层 和 User、Article 等代码，需要手动删除后，再次运行代码生成器 CodeGenerator 。</p><h2 id="自动注入"><a href="#自动注入" aria-hidden="true" class="header-anchor">#</a> 自动注入</h2><p>Jboot 通过 Google Guice 提供了强健稳定的代码注入功能，使用注入功能只需要了解一下三个注解：</p><ol><li>@Bean : 声明此类可以被自动注入</li><li>@Inject : 对属性进行赋值注入</li><li>@Singleton : 申明此类为单例模式，通常和@Bean 一起使用。</li></ol><p>通过代码生成器生成的Service层代码就已经默认添加上了 @Bean 和 @Singleton 这两个配置，生成的代码如下：</p><pre class="language-java"><code><span class="token keyword">package</span> com<span class="token punctuation">.</span>xxx<span class="token punctuation">.</span>service<span class="token punctuation">.</span>impl<span class="token punctuation">;</span>

<span class="token keyword">import</span> io<span class="token punctuation">.</span>jboot<span class="token punctuation">.</span>aop<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span>Bean<span class="token punctuation">;</span>
<span class="token keyword">import</span> com<span class="token punctuation">.</span>xxx<span class="token punctuation">.</span>service<span class="token punctuation">.</span>UserService<span class="token punctuation">;</span>
<span class="token keyword">import</span> com<span class="token punctuation">.</span>xxx<span class="token punctuation">.</span>model<span class="token punctuation">.</span>User<span class="token punctuation">;</span>
<span class="token keyword">import</span> io<span class="token punctuation">.</span>jboot<span class="token punctuation">.</span>service<span class="token punctuation">.</span>JbootServiceBase<span class="token punctuation">;</span>

<span class="token keyword">import</span> javax<span class="token punctuation">.</span>inject<span class="token punctuation">.</span>Singleton<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@Singleton</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">extends</span> <span class="token class-name">JbootServiceBase</span><span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
</code></pre><p>我们使用到 UserService 接口的时候，只需要添加 @Inject 注解即可，例如：在 IndexController 需要用到 UserService，代码如下：</p><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IndexController</span> <span class="token keyword">extends</span> <span class="token class-name">JbootController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Inject</span>
    <span class="token keyword">private</span> UserService userService<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">renderText</span><span class="token punctuation">(</span><span class="token string">&quot;Hello World Jboot&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">dbtest</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        List<span class="token generics function"><span class="token punctuation">&lt;</span>Record<span class="token punctuation">&gt;</span></span> records <span class="token operator">=</span> Db<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;select * from user&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">renderText</span><span class="token punctuation">(</span>Arrays<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>records<span class="token punctuation">.</span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>


    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">users</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 这里用到了 userService 的查询方法</span>
        List<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> users <span class="token operator">=</span> userService<span class="token punctuation">.</span><span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">renderText</span><span class="token punctuation">(</span>Arrays<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>users<span class="token punctuation">.</span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>


    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        Jboot<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>运行 <code>main()</code> 方法后，我们通过浏览访问 <code>http://127.0.0.1:8080/users</code> ，此时，页面显示的内容和 访问 <code>http://127.0.0.1:8080/dbtest</code> 的效果是一样的：
<img src="/assets/img/0009.6e2b7902.png" alt></p><h2 id="数据库的增删改查"><a href="#数据库的增删改查" aria-hidden="true" class="header-anchor">#</a> 数据库的增删改查</h2><p>在本章节，我们要完成一个小型的项目，这个项目是一个用户管理系统，他具有以下功能：</p><ul><li>显示用户列表，带有分页的功能</li><li>可以对单个用户删除</li><li>可以对用户进行修改</li><li>可以添加新的用户</li></ul><h3 id="分页查询"><a href="#分页查询" aria-hidden="true" class="header-anchor">#</a> 分页查询</h3><p>我们可以继续来改造 IndexController，通过修改代码生成器的生成的 UserService，来达到上述要求的功能。</p><p>在上述的章节里，我们知道，通过如下的代码可以获得所有的用户信息：</p><pre class="language-java"><code> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">users</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    List<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> users <span class="token operator">=</span> userService<span class="token punctuation">.</span><span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">renderText</span><span class="token punctuation">(</span>Arrays<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>users<span class="token punctuation">.</span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>如果要分页，我们需要在UserService添加一个分页的方法，并在 UserServiceImpl 来实现这个分页的方法，代码如下：</p><p>UserService.java</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

    <span class="token comment">// 代码生成器生成的其他方法略</span>
    <span class="token comment">//...</span>

    <span class="token keyword">public</span> Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token function">paginate</span><span class="token punctuation">(</span><span class="token keyword">int</span> page<span class="token punctuation">,</span> <span class="token keyword">int</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>UserServiceImpl.java</p><pre class="language-java"><code><span class="token annotation punctuation">@Bean</span>
<span class="token annotation punctuation">@Singleton</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">extends</span> <span class="token class-name">JbootServiceBase</span><span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token function">paginate</span><span class="token punctuation">(</span><span class="token keyword">int</span> page<span class="token punctuation">,</span> <span class="token keyword">int</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> DAO<span class="token punctuation">.</span><span class="token function">paginate</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>为了代码更加简洁直观，我们新建一个 UserController 来做用户相关的增删改查功能，代码如下：</p><pre class="language-java"><code><span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/user&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">JbootController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Inject</span>
    <span class="token keyword">private</span> UserService userService<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">int</span> page <span class="token operator">=</span> <span class="token function">getParaToInt</span><span class="token punctuation">(</span><span class="token string">&quot;page&quot;</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> userPage <span class="token operator">=</span> userService<span class="token punctuation">.</span><span class="token function">paginate</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">setAttr</span><span class="token punctuation">(</span><span class="token string">&quot;pageData&quot;</span><span class="token punctuation">,</span> userPage<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">render</span><span class="token punctuation">(</span><span class="token string">&quot;/user.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre><ul><li><code>getParaToInt()</code> 可以获得request提交过来的page数据，例如：http://127.0.0.1:8080/user?page=100 ，此时，代码里 page 的值是 100，当不传值得时候，默认值是 1 。</li><li>通过 userService.paginate 查询数据库，返回一个 Page 对象，里面包含了 当前页码、总页码 和 数据列表等信息。</li><li>通过 <code>setAttr()</code> 把数据结果传递到页面</li></ul><p>把数据传递到 user.html 后，需要 user.html 把具体的数据和分页相关在网页上列出来。</p><p>第一步：完善数据的显示，user.html内容如下：</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>table</span> <span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>ID<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>登录名<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>密码<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #for(user : pageData.list )
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.id)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.login_name)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.password)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>table</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>此时，运行 <code>main()</code> 方法，访问 <code>http://127.0.0.1:8080/user</code> ，页面显示内容如下：</p><p><img src="/assets/img/0011.17c00c99.png" alt></p><p>第二步：完善分页功能。</p><p>Jboot应用的分页功能需要自定义一个分页标签，自定义分页标签非常简单，代码内容如下：</p><pre class="language-java"><code><span class="token annotation punctuation">@JFinalDirective</span><span class="token punctuation">(</span><span class="token string">&quot;myPaginate&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyPaginateDirective</span> <span class="token keyword">extends</span> <span class="token class-name">JbootPaginateDirective</span> <span class="token punctuation">{</span>

    <span class="token keyword">protected</span> String <span class="token function">getPageAttrName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">&quot;pageData&quot;</span><span class="token punctuation">;</span> <span class="token comment">//这个值要和Controller里setAttr的第一个参数值相同</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre><p>然后再修改 user.html 内容如下：</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>table</span> <span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>ID<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>登录名<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>密码<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #for(user : pageData.list )
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.id)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.login_name)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.password)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>table</span><span class="token punctuation">&gt;</span></span>
#myPaginate()
    #for(page : pages)
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>#(page.url??)<span class="token punctuation">&quot;</span></span> <span class="token punctuation">&gt;</span></span>#(page.text??)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
    #end
#end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>此时，运行 <code>main()</code> 方法，访问 <code>http://127.0.0.1:8080/user</code> ，页面显示内容如下：</p><p><img src="/assets/img/0012.dfff97ac.png" alt></p><p>由于数据量太小，同时在我们的代码里，要求每页显示10条数据，所以页面才显示了第一页，当我们在数据库添加数据量超过10条的时候，页面显示内容如下：</p><p><img src="/assets/img/0013.9982e36f.png" alt></p><p>同时，上一页、下一页等功能正常使用，如下图：</p><p><img src="/assets/img/0014.ad262703.png" alt></p><p>实际上，#myPaginate() 自定义分页标签还可以做更多的配置，包括功能和样式等，但是这不是本章节要讨论的内容了。</p><h3 id="新增功能"><a href="#新增功能" aria-hidden="true" class="header-anchor">#</a> 新增功能</h3><p>为了实现新增功能，我们需要写一个叫 add.html 的页面，并写对应的 Controller，保证可以访问。</p><p>add.html 的代码如下：</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user add<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/user/doSave<span class="token punctuation">&quot;</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>post<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    登录名： <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>login_name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">/&gt;</span></span>
    密码： <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>password<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>提交数据<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>通过 add.html 内容我们能看到，当用户点击 <code>提交数据</code> 按钮的时候，页面会把数据提交到 <code>/user/doSave</code> 这个路径上去，所以，需要我们在 UserController 编写一个叫做 <code>doSave（）</code> 的方法来接收数据，并保存到数据库。</p><p>doSave() 方法内容如下：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">doSave</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    String loginName <span class="token operator">=</span> <span class="token function">getPara</span><span class="token punctuation">(</span><span class="token string">&quot;login_name&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    String password <span class="token operator">=</span> <span class="token function">getPara</span><span class="token punctuation">(</span><span class="token string">&quot;password&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    User user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    user<span class="token punctuation">.</span><span class="token function">setLoginName</span><span class="token punctuation">(</span>loginName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    user<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">;</span>

    user<span class="token punctuation">.</span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string">&quot;/user&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p><code>doSave(）</code> 方法的主要作用是接收数据、把数据保存到数据库、然后跳转到 <code>/user</code> 这个页面去。</p><h3 id="修改功能"><a href="#修改功能" aria-hidden="true" class="header-anchor">#</a> 修改功能</h3><p>为了减少代码量，我们直接把 add.html 改造成为可用做新增，也可以用作修改的功能（通常在商业项目中也会这么做），因此，我们需要简单修改下 add.html 代码和 add() 这个方法的代码。</p><p>add.html</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user add<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/user/doSave<span class="token punctuation">&quot;</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>post<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>hidden<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>id<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>#(id ??)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    登录名： <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>login_name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">/&gt;</span></span>
    密码： <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>password<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>br</span><span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>提交数据<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>和新增功能的html对比，增加了 <code>&lt;input type=&quot;hidden&quot; name=&quot;id&quot; value=&quot;#(id ??)&quot;&gt;</code> 这行代码。</p><p>add() 方法内容如下：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">int</span> id <span class="token operator">=</span> <span class="token function">getParaToInt</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>id <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//有id ，说明有数据提交过来，用来做修改的标识。</span>
        <span class="token function">setAttr</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">,</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token string">&quot;/add.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>同时， doSave()方法也需要修改下，用来区分是新增还是修改，代码如下：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">doSave</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    String loginName <span class="token operator">=</span> <span class="token function">getPara</span><span class="token punctuation">(</span><span class="token string">&quot;login_name&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    String password <span class="token operator">=</span> <span class="token function">getPara</span><span class="token punctuation">(</span><span class="token string">&quot;password&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">long</span> id <span class="token operator">=</span> <span class="token function">getParaToLong</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">,</span><span class="token number">0</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span>


    User user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    user<span class="token punctuation">.</span><span class="token function">setLoginName</span><span class="token punctuation">(</span>loginName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    user<span class="token punctuation">.</span><span class="token function">setPassword</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token keyword">if</span> <span class="token punctuation">(</span>id <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//说明是更新</span>
        user<span class="token punctuation">.</span><span class="token function">setId</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        user<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">//说明是新增</span>
        user<span class="token punctuation">.</span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string">&quot;/user&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>最后，我们在改造下 user.html ,在表格的后面添加一个 <code>修改</code> 的连接， user.html 代码如下：</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>table</span> <span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>ID<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>登录名<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>密码<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>操作<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #for(user : pageData.list )
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.id)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.login_name)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.password)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/user/add?id=#(user.id)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>修改<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>table</span><span class="token punctuation">&gt;</span></span>
#myPaginate()
    #for(page : pages)
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>#(page.url??)<span class="token punctuation">&quot;</span></span> <span class="token punctuation">&gt;</span></span>#(page.text??)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
    #end
#end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>此时，页面内容如下，修改功能正常使用。
<img src="/assets/img/0015.b5db3cb9.png" alt></p><h3 id="删除功能"><a href="#删除功能" aria-hidden="true" class="header-anchor">#</a> 删除功能</h3><p>删除功能更加简单，只需要在Controller接收ID，然后调用 userService.delete() 方法就可以了，改造 user.html 代码如下：</p><pre class="language-html"><code><span class="token doctype">&lt;!DOCTYPE html&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>en<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>UTF-8<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>user index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>table</span> <span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>ID<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>登录名<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>密码<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>th</span><span class="token punctuation">&gt;</span></span>操作<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>th</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #for(user : pageData.list )
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>tr</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.id)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.login_name)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>#(user.password)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>td</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/user/add?id=#(user.id)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>修改<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/user/del?id=#(user.id)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>删除<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>td</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>tr</span><span class="token punctuation">&gt;</span></span>
    #end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>table</span><span class="token punctuation">&gt;</span></span>
#myPaginate()
    #for(page : pages)
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>#(page.url??)<span class="token punctuation">&quot;</span></span> <span class="token punctuation">&gt;</span></span>#(page.text??)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
    #end
#end
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>页面显示如下：
<img src="/assets/img/0016.9625facb.png" alt></p><p>我们只需要在 UserController 编写一个 del() 方法，接收id、删除数据库数据，并跳转回 /user 即可完成任务，代码如下：</p><pre class="language-java"><code>  <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">del</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">long</span> id <span class="token operator">=</span> <span class="token function">getParaToLong</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">,</span><span class="token number">0</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span>
    userService<span class="token punctuation">.</span><span class="token function">deleteById</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string">&quot;/user&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre><p>到目前为止，增删改查所有功能完成。</p><h2 id="使用缓存提高性能"><a href="#使用缓存提高性能" aria-hidden="true" class="header-anchor">#</a> 使用缓存提高性能</h2><p>通过以上内容，我们可以使用Jboot开发一个具有增、删、改、查基本功能的Java Web 应用，但是，在互联网的应用里，高并发的要求可以说是必不可少的，缓存在提高应用性能和并发上有绝对的话语权。</p><p>在 Jboot 里，我们如何来使用缓存呢？</p><p>Jboot 提供了两种方案：</p><ol><li>注解</li><li>手写代码</li></ol><p>在注解中，Jboot提供了4个注解，方便的对缓存进行操作，他们分别是：</p><ul><li>@Cacheable</li><li>@CachePut</li><li>@CacheEvict</li><li>@CachesEvict</li></ul><p>如何来使用呢？</p><p>在以上的章节里，我们知道，如下的代码是一个分页查询的功能：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">extends</span> <span class="token class-name">JbootServiceBase</span><span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token function">paginate</span><span class="token punctuation">(</span><span class="token keyword">int</span> page<span class="token punctuation">,</span> <span class="token keyword">int</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> DAO<span class="token punctuation">.</span><span class="token function">paginate</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>如何来让 <code>paginate(int page, int size)</code> 方法具有缓存的功能呢？</p><p>非常简单：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">extends</span> <span class="token class-name">JbootServiceBase</span><span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Cacheable</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;myCache&quot;</span><span class="token punctuation">,</span>key <span class="token operator">=</span> <span class="token string">&quot;page:#(page)-#(size)&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token function">paginate</span><span class="token punctuation">(</span><span class="token keyword">int</span> page<span class="token punctuation">,</span> <span class="token keyword">int</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> DAO<span class="token punctuation">.</span><span class="token function">paginate</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>只需要添加 <code>@Cacheable(name = &quot;myCache&quot;,key = &quot;page:#(page)-#(size)&quot;)</code> 这个注解。</p><p>在Jboot中，默认的缓存为 <code>EhCache</code> , 这个注解的含义是：</p><ul><li>在EhCache中创建一个缓存为myCache的缓存区</li><li>当查询第 1 页的时候，缓存的key为：<code>page:1-10</code>，因为 <code>paginate(int page, int size)</code> 方法在执行的时候，传递过来的值分别是：page=1，size=10</li><li>当查询第 2 页的时候，缓存的key为：<code>page:2-10</code>，原因同上。</li></ul><p>当 <code>paginate(int page, int size)</code> 方法使用 @Cacheable 缓存之后，只有第一次访问的时候去查询数据库，之后的访问会直接从缓存中获取数据，大大提高了性能。</p><p>但是...</p><p>使用缓存也会带来一些问题，因为 <code>paginate(int page, int size)</code> 方法不再访问数据库，从而导致我们在数据库对数据进行增、删、改，这个页面数据都不会再发生变化。</p><p>要让 <code>paginate(int page, int size)</code> 方法与数据库同步，怎么办呢？</p><p>需要我们在对数据库进行 增、删、改 的时候，清除这个方法里的缓存数据。</p><p>代码如下：</p><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">extends</span> <span class="token class-name">JbootServiceBase</span><span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Cacheable</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;myCache&quot;</span><span class="token punctuation">,</span>key <span class="token operator">=</span> <span class="token string">&quot;page:#(page)-#(size)&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> Page<span class="token generics function"><span class="token punctuation">&lt;</span>User<span class="token punctuation">&gt;</span></span> <span class="token function">paginate</span><span class="token punctuation">(</span><span class="token keyword">int</span> page<span class="token punctuation">,</span> <span class="token keyword">int</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> DAO<span class="token punctuation">.</span><span class="token function">paginate</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token annotation punctuation">@CacheEvict</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;myCache&quot;</span><span class="token punctuation">,</span>key <span class="token operator">=</span> <span class="token string">&quot;*&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">save</span><span class="token punctuation">(</span>User model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">save</span><span class="token punctuation">(</span>model<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token annotation punctuation">@CacheEvict</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;myCache&quot;</span><span class="token punctuation">,</span>key <span class="token operator">=</span> <span class="token string">&quot;*&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">update</span><span class="token punctuation">(</span>User model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span>model<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token annotation punctuation">@CacheEvict</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">&quot;myCache&quot;</span><span class="token punctuation">,</span>key <span class="token operator">=</span> <span class="token string">&quot;*&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">delete</span><span class="token punctuation">(</span>User model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>model<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><p>重写父类 <code>JbootServiceBase</code> 的增、删、改的方法，在这些方法添加 <code>@CacheEvict(name = &quot;myCache&quot;,key = &quot;*&quot;)</code> 注解。</p><p><strong>被添加@CacheEvict的方法，在执行之后，会清除 name 为 myCache 的所有key。</strong> 也就是清除 <code>paginate(int page, int size)</code> 方法所有的 key 。</p><p>这样，就做到了 <code>paginate(int page, int size)</code> 方法与数据库同步的功能了。是不是非常简单呢 ？！</p><p>不过 ...</p><p>以上，只是 Jboot 缓存功能的冰山一角，Jboot 的缓存非常强大，比如：</p><ul><li>@CachePut 和 @CachesEvict 又如何使用？什么场景下使用？</li><li>如何使用 Redis 或者其他的缓存方案代替默认的 EhCache ，甚至是公司自己内部的缓存方案 ?</li><li>分布式缓存如何做 ?</li><li>如何设置缓存的失效时间 ?</li><li>如何做到整个网页缓存，类似页面静态化？</li><li>等等等等</li></ul><p>Jboot 都给与类非常完美的支持。</p><h2 id="探索jboot的更多功能"><a href="#探索jboot的更多功能" aria-hidden="true" class="header-anchor">#</a> 探索Jboot的更多功能...</h2><p>恭喜你，到目前为止，你已经掌握了使用 Jboot 来开发一个 java web 的基本技能，包含了</p><ul><li>MVC</li><li>ORM</li><li>AOP</li><li>代码生成器</li><li>使用缓存提高性能</li><li>等等</li></ul><p>这是非常重要的一步。</p><p>但是，Jboot 的功能远远不止这些，以上只是 Jboot 的冰山一角。</p><p>Jboot 真正的核心是做微服务的开发，微服务的底层代码是分布式调用RPC，RPC 的框架和实现的方案非常繁杂，不过 Jboot 已经支持了主流 RPC 的实现，其中包含了 Dubbo 、motan、Zbus等， 未来还会添加 gRPC 等更多的支持。</p><ul><li>在 RPC 下，Jboot 支持了 RPC 下的 熔断、降级、监控、Opentracing等等功能</li><li>在分布式下，Jboot 支持了分布式缓存、分布式Session、分布式锁、分布式任务、统一配置中心</li><li>在数据库下，Jboot 支持分库分表、支持 Reids 等nosql数据库的极简调用</li><li>在 MQ 下，Jboot 支持 rabbitmq、redismq、zbus 甚至还支持了 阿里云的商业MQ</li><li>另外，Jboot还支持了Swagger、Event事件机制、高并发下的限流方案等等更多的惊喜</li></ul><p>希望你用的顺手、开心，如果有什么问题，可以通过 顶部菜单的 提问 链接进行提问，我回在第一时间回复您。</p></div><!----><!----></div></div></div>
    <script src="/assets/js/0.06af09ca.js" defer></script><script src="/assets/js/app.7f52c12a.js" defer></script>
  </body>
</html>
